home *** CD-ROM | disk | FTP | other *** search
/ Pascal Super Library / Pascal Super Library (CW International)(1997).bin / DELPHI32 / COMPNENT / ISAMEXPT / ISAMNAV.PAS < prev    next >
Pascal/Delphi Source File  |  1996-04-04  |  14KB  |  519 lines

  1. unit Isamnav;
  2. {copyright 1995 by Norbert Stellberg GmbH}
  3. interface
  4.  
  5. Uses Classes, WinProcs, WinTypes, ExtCtrls, Controls,
  6.      IsamBrow, DbCtrls, Messages, Buttons;
  7.  
  8. Type
  9.   TIsamNavButton = class;
  10.   TIsamNavigateBtn = (nbFirst, nbPrior, nbNext, nbLast,
  11.                       nbInsert, nbDelete);
  12.   TIsamButtonSet = set of TIsamNavigateBtn;
  13.  
  14. { tIsamNavigator }
  15.  
  16.   TIsamNavigator = class (TCustomPanel)
  17.   {NAVIGATOR for isamtables, compatible with NAVIGATORS
  18.    for IDAPI-driven tables.}
  19.   private
  20.     FBrowser: TIsamBrowser;
  21.     FVisibleButtons: TIsamButtonSet;
  22.     FHints: TStrings;
  23.     ButtonWidth: Integer;
  24.     MinBtnSize: TPoint;
  25.     FOnNavClick: ENavClick;
  26.     FocusedButton: TIsamNavigateBtn;
  27.     FConfirmDelete: Boolean;
  28.     procedure SetBrowser(Value: TIsamBrowser);
  29.     procedure InitButtons;
  30.     procedure InitHints;
  31.     procedure Click(Sender: TObject);
  32.     procedure BtnMouseDown (Sender: TObject; Button: TMouseButton;
  33.       Shift: TShiftState; X, Y: Integer);
  34.     procedure SetVisible(Value: TIsamButtonSet);
  35.     procedure AdjustSize (var W: Integer; var H: Integer);
  36.     procedure SetHints(Value: TStrings);
  37.     procedure WMSize(var Message: TWMSize);  message WM_SIZE;
  38.     procedure WMSetFocus(var Message: TWMSetFocus); message WM_SETFOCUS;
  39.     procedure WMKillFocus(var Message: TWMKillFocus); message WM_KILLFOCUS;
  40.     procedure WMGetDlgCode(var Message: TWMGetDlgCode); message WM_GETDLGCODE;
  41.     procedure CMEnabledChanged(var Message: TMessage); message CM_ENABLEDCHANGED;
  42.   protected
  43.     Buttons: array[TIsamNavigateBtn] of tIsamNavButton;
  44.     procedure DataChanged;
  45.     procedure EditingChanged;
  46.     procedure ActiveChanged;
  47.     procedure Loaded; override;
  48.     procedure KeyDown(var Key: Word; Shift: TShiftState); override;
  49.     procedure Notification(AComponent: TComponent;
  50.       Operation: TOperation); override;
  51.   public
  52.     constructor Create(AOwner: TComponent); override;
  53.     destructor Destroy; override;
  54.     procedure SetBounds(ALeft, ATop, AWidth, AHeight: Integer); override;
  55.     procedure BtnClick(Index: tIsamNavigateBtn);
  56.   published
  57.     property Browser: TIsamBrowser read FBrowser write SetBrowser;
  58.     property VisibleButtons: TIsamButtonSet read FVisibleButtons write SetVisible
  59.       default [nbFirst, nbPrior, nbNext, nbLast, nbInsert, nbDelete];
  60.     property Align;
  61.     property DragCursor;
  62.     property DragMode;
  63.     property Enabled;
  64.     property Ctl3D;
  65.     property Hints: TStrings read FHints write SetHints;
  66.     property ParentCtl3D;
  67.     property ParentShowHint;
  68.     property ConfirmDelete: Boolean read FConfirmDelete write FConfirmDelete default True;
  69.     property ShowHint;
  70.     property TabOrder;
  71.     property TabStop;
  72.     property Visible;
  73.     property OnClick: ENavClick read FOnNavClick write FOnNavClick;
  74.     property OnDblClick;
  75.     property OnDragDrop;
  76.     property OnDragOver;
  77.     property OnEndDrag;
  78.     property OnEnter;
  79.     property OnExit;
  80.     property OnResize;
  81.   end;
  82.  
  83. { tIsamNavButton }
  84.  
  85.   tIsamNavButton = class(TSpeedButton)
  86.   private
  87.     FIndex: TIsamNavigateBtn;
  88.     FNavStyle: tNavButtonStyle;
  89.     FRepeatTimer: TTimer;
  90.     procedure TimerExpired(Sender: TObject);
  91.   protected
  92.     procedure Paint; override;
  93.     procedure MouseDown(Button: TMouseButton; Shift: TShiftState;
  94.       X, Y: Integer); override;
  95.     procedure MouseUp(Button: TMouseButton; Shift: TShiftState;
  96.       X, Y: Integer); override;
  97.   public
  98.     destructor Destroy; override;
  99.     property NavStyle: tNavButtonStyle read FNavStyle write FNavStyle;
  100.     property Index : TIsamNavigateBtn read FIndex write FIndex;
  101.   end;
  102.  
  103. implementation
  104.  
  105. Uses DbConsts, SysUtils, Forms, Dialogs;
  106.  
  107. const
  108.   BtnStateName: array[TNavGlyph] of PChar = ('EN', 'DI');
  109.   BtnTypeName: array[TIsamNavigateBtn] of PChar = ('FIRST', 'PRIOR', 'NEXT',
  110.     'LAST', 'INSERT', 'DELETE');
  111.   BtnHintId: array[TIsamNavigateBtn] of Word = (SFirstRecord, SPriorRecord,
  112.     SNextRecord, SLastRecord, SInsertRecord, SDeleteRecord);
  113.  
  114. constructor tIsamNavigator.Create(AOwner: TComponent);
  115. begin
  116.   inherited Create(AOwner); 
  117.   ControlStyle := ControlStyle - [csAcceptsControls, csSetCaption] +
  118.     [csFramed, csOpaque];
  119.   FVisibleButtons := [nbFirst, nbPrior, nbNext, nbLast, nbInsert, nbDelete];
  120.   FHints := TStringList.Create;
  121.   InitButtons;
  122.   BevelOuter := bvNone;
  123.   BevelInner := bvNone;
  124.   Width := 241;
  125.   Height := 25;
  126.   ButtonWidth := 0;
  127.   FocusedButton := nbFirst;
  128.   FConfirmDelete := True;
  129. end;
  130.           
  131. destructor tIsamNavigator.Destroy;
  132. begin
  133.   {FDataLink.Free;
  134.   FDataLink := nil;}
  135.   FHints.Free;
  136.   inherited Destroy;
  137. end;
  138.  
  139. procedure tIsamNavigator.InitButtons;
  140. var
  141.   I: TIsamNavigateBtn;
  142.   Btn: tIsamNavButton;
  143.   X: Integer;
  144.   ResName: array[0..40] of Char;
  145. begin
  146.   MinBtnSize := Point(20, 18);
  147.   X := 0;
  148.   for I := Low(Buttons) to High(Buttons) do
  149.   begin
  150.     Btn := tIsamNavButton.Create (Self);
  151.     Btn.Index := I;
  152.     Btn.Visible := I in FVisibleButtons;
  153.     Btn.Enabled := True;
  154.     Btn.SetBounds (X, 0, MinBtnSize.X, MinBtnSize.Y);
  155.     Btn.Glyph.Handle := LoadBitmap(HInstance,
  156.         StrFmt(ResName, 'dbn_%s', [BtnTypeName[I]]));
  157.     Btn.NumGlyphs := 2;
  158.     Btn.OnClick := Click;
  159.     Btn.OnMouseDown := BtnMouseDown;
  160.     Btn.Parent := Self;
  161.     Buttons[I] := Btn;
  162.     X := X + MinBtnSize.X;
  163.   end;
  164.   InitHints;
  165.   Buttons[nbPrior].NavStyle := Buttons[nbPrior].NavStyle + [nsAllowTimer];
  166.   Buttons[nbNext].NavStyle  := Buttons[nbNext].NavStyle + [nsAllowTimer];
  167. end;
  168.  
  169. procedure tIsamNavigator.InitHints;
  170. var
  171.   I: Integer;
  172.   J: TIsamNavigateBtn;
  173. begin
  174.   for J := Low(Buttons) to High(Buttons) do
  175.     Buttons[J].Hint := LoadStr (BtnHintId[J]);
  176.   J := Low(Buttons);
  177.   for I := 0 to (FHints.Count - 1) do
  178.   begin
  179.     if FHints.Strings[I] <> '' then Buttons[J].Hint := FHints.Strings[I];
  180.     if J = High(Buttons) then Exit;
  181.     Inc(J);
  182.   end;
  183. end;
  184.  
  185. procedure tIsamNavigator.SetHints(Value: TStrings);
  186. begin
  187.   FHints.Assign(Value);
  188.   InitHints;
  189. end;
  190.  
  191. procedure tIsamNavigator.Notification(AComponent: TComponent;
  192.   Operation: TOperation);
  193. begin
  194.   inherited Notification(AComponent, Operation);
  195.   {if (Operation = opRemove) and (FDataLink <> nil) and
  196.     (AComponent = DataSource) then DataSource := nil;}
  197. end;
  198.  
  199. procedure tIsamNavigator.DataChanged;
  200. begin
  201. end;
  202.  
  203. procedure tIsamNavigator.EditingChanged;
  204. begin
  205. end;
  206.  
  207. procedure tIsamNavigator.SetVisible(Value: TIsamButtonSet);
  208. var
  209.   I: tIsamNavigateBtn;
  210.   W, H: Integer;
  211. begin
  212.   W := Width;
  213.   H := Height;
  214.   FVisibleButtons := Value;
  215.   for I := Low(Buttons) to High(Buttons) do
  216.     Buttons[I].Visible := I in FVisibleButtons;
  217.   AdjustSize (W, H);
  218.   if (W <> Width) or (H <> Height) then
  219.     inherited SetBounds (Left, Top, W, H);
  220.   Invalidate;
  221. end;
  222.  
  223. procedure tIsamNavigator.AdjustSize (var W: Integer; var H: Integer);
  224. var
  225.   Count: Integer;
  226.   MinW: Integer;
  227.   I: tIsamNavigateBtn;
  228.   LastBtn: tIsamNavigateBtn;
  229.   Space, Temp, Remain: Integer;
  230.   X: Integer;
  231. begin
  232.   if (csLoading in ComponentState) then Exit;
  233.   if Buttons[nbFirst] = nil then Exit;
  234.  
  235.   Count := 0;
  236.   LastBtn := High(Buttons);
  237.   for I := Low(Buttons) to High(Buttons) do
  238.   begin
  239.     if Buttons[I].Visible then
  240.     begin
  241.       Inc(Count);
  242.       LastBtn := I;
  243.     end;
  244.   end;
  245.   if Count = 0 then Inc(Count);
  246.  
  247.   MinW := Count * (MinBtnSize.X - 1) + 1;
  248.   if W < MinW then
  249.     W := MinW;
  250.   if H < MinBtnSize.Y then
  251.     H := MinBtnSize.Y;
  252.  
  253.   ButtonWidth := ((W - 1) div Count) + 1;
  254.   Temp := Count * (ButtonWidth - 1) + 1;
  255.   if Align = alNone then
  256.     W := Temp;
  257.  
  258.   X := 0;
  259.   Remain := W - Temp;
  260.   Temp := Count div 2;
  261.   for I := Low(Buttons) to High(Buttons) do
  262.   begin
  263.     if Buttons[I].Visible then
  264.     begin
  265.       Space := 0;
  266.       if Remain <> 0 then
  267.       begin
  268.         Dec (Temp, Remain);
  269.         if Temp < 0 then
  270.         begin
  271.           Inc (Temp, Count);
  272.           Space := 1;
  273.         end;
  274.       end;
  275.       Buttons[I].SetBounds (X, 0, ButtonWidth + Space, Height);
  276.       Inc (X, ButtonWidth - 1 + Space);
  277.       LastBtn := I;
  278.     end
  279.     else
  280.       Buttons[I].SetBounds (Width + 1, 0, ButtonWidth, Height);
  281.   end;
  282. end;
  283.  
  284. procedure tIsamNavigator.SetBounds(ALeft, ATop, AWidth, AHeight: Integer);
  285. var
  286.   W, H: Integer;
  287. begin
  288.   W := AWidth;
  289.   H := AHeight;
  290.   AdjustSize (W, H);
  291.   inherited SetBounds (ALeft, ATop, W, H);
  292. end;
  293.  
  294. procedure tIsamNavigator.WMSize(var Message: TWMSize);
  295. var
  296.   W, H: Integer;
  297. begin
  298.   inherited;
  299.  
  300.   { check for minimum size }
  301.   W := Width;
  302.   H := Height;
  303.   AdjustSize (W, H);
  304.   if (W <> Width) or (H <> Height) then
  305.     inherited SetBounds(Left, Top, W, H);
  306.   Message.Result := 0;
  307. end;
  308.  
  309. procedure tIsamNavigator.Click(Sender: TObject);
  310. begin
  311.   BtnClick (tIsamNavButton (Sender).Index);
  312. end;
  313.  
  314. procedure tIsamNavigator.BtnMouseDown(Sender: TObject; Button: TMouseButton;
  315.   Shift: TShiftState; X, Y: Integer);
  316. var
  317.   OldFocus: tIsamNavigateBtn;
  318.   Form: TForm;
  319. begin
  320.   OldFocus := FocusedButton;
  321.   FocusedButton := tIsamNavButton (Sender).Index;
  322.   if TabStop and (GetFocus <> Handle) and CanFocus then
  323.   begin
  324.     SetFocus;
  325.     if (GetFocus <> Handle) then
  326.       Exit;
  327.   end
  328.   else if TabStop and (GetFocus = Handle) and (OldFocus <> FocusedButton) then
  329.   begin
  330.     Buttons[OldFocus].Invalidate;
  331.     Buttons[FocusedButton].Invalidate;
  332.   end;
  333. end;
  334.  
  335. procedure tIsamNavigator.BtnClick(Index: tIsamNavigateBtn);
  336. begin
  337.   if Assigned(FBrowser) then begin
  338.     if Browser <> NIL then begin
  339.       if Browser.Table <> NIL then with Browser do begin
  340.         case Index of
  341.           nbPrior: SendMessage(Browser.Handle, WM_KeyDown, vk_UP, 0);
  342.           nbNext : SendMessage(Browser.Handle, WM_KeyDown, vk_Down, 0);
  343.           nbFirst: SetAndupDateBrowserScreen('',0);
  344.           nbLast : SetAndupdateBrowserScreen(#255,9999999);
  345.           nbInsert: SendMessage(Browser.Handle, WM_KeyDown, vk_Insert, 0);
  346.           nbDelete: begin
  347.                       if not FConfirmDelete or (MessageDlg (LoadStr(SDeleteRecordQuestion),
  348.                              mtConfirmation, mbOKCancel, 0) <> idCancel) then
  349.                       SendMessage(Browser.Handle, WM_KeyDown, vk_Delete, 0);
  350.                     end;
  351.         end;
  352.       end;
  353.     end;
  354.   end;
  355.   if not (csDesigning in ComponentState) and Assigned(FOnNavClick) then {FOnNavClick(Self, Index)};
  356. end;
  357.  
  358. procedure tIsamNavigator.WMSetFocus(var Message: TWMSetFocus);
  359. begin
  360.   Buttons[FocusedButton].Invalidate;
  361. end;
  362.  
  363. procedure tIsamNavigator.WMKillFocus(var Message: TWMKillFocus);
  364. begin
  365.   Buttons[FocusedButton].Invalidate;
  366. end;
  367.  
  368. procedure tIsamNavigator.KeyDown(var Key: Word; Shift: TShiftState);
  369. var
  370.   NewFocus: tIsamNavigateBtn;
  371.   OldFocus: tIsamNavigateBtn;
  372. begin
  373.   OldFocus := FocusedButton;
  374.   case Key of
  375.     VK_RIGHT:
  376.       begin
  377.         NewFocus := FocusedButton;
  378.         repeat
  379.           if NewFocus < High(Buttons) then
  380.             NewFocus := Succ(NewFocus);
  381.         until (NewFocus = High(Buttons)) or (Buttons[NewFocus].Visible);
  382.         if NewFocus <> FocusedButton then
  383.         begin
  384.           FocusedButton := NewFocus;
  385.           Buttons[OldFocus].Invalidate;
  386.           Buttons[FocusedButton].Invalidate;
  387.         end;
  388.       end;
  389.     VK_LEFT:
  390.       begin
  391.         NewFocus := FocusedButton;
  392.         repeat
  393.           if NewFocus > Low(Buttons) then
  394.             NewFocus := Pred(NewFocus);
  395.         until (NewFocus = Low(Buttons)) or (Buttons[NewFocus].Visible);
  396.         if NewFocus <> FocusedButton then
  397.         begin
  398.           FocusedButton := NewFocus;
  399.           Buttons[OldFocus].Invalidate;
  400.           Buttons[FocusedButton].Invalidate;
  401.         end;
  402.       end;
  403.     VK_SPACE:
  404.       begin
  405.         if Buttons[FocusedButton].Enabled then
  406.           Buttons[FocusedButton].Click;
  407.       end;
  408.   end;
  409. end;
  410.  
  411. procedure tIsamNavigator.WMGetDlgCode(var Message: TWMGetDlgCode);
  412. begin
  413.   Message.Result := DLGC_WANTARROWS;
  414. end;
  415.  
  416. procedure tIsamNavigator.ActiveChanged;
  417. var
  418.   I: tIsamNavigateBtn;
  419. begin
  420.   if not (Enabled) then
  421.     for I := Low(Buttons) to High(Buttons) do
  422.       Buttons[I].Enabled := False
  423.   else
  424.   begin
  425.     DataChanged;
  426.     EditingChanged;
  427.   end;
  428. end;
  429.                   
  430. procedure tIsamNavigator.CMEnabledChanged(var Message: TMessage);
  431. begin
  432.   inherited;
  433.   if not (csLoading in ComponentState) then
  434.     ActiveChanged;
  435. end;
  436.  
  437. procedure tIsamNavigator.Loaded;
  438. var
  439.   W, H: Integer;
  440. begin
  441.   inherited Loaded;
  442.   W := Width;
  443.   H := Height;
  444.   AdjustSize (W, H);
  445.   if (W <> Width) or (H <> Height) then
  446.     inherited SetBounds (Left, Top, W, H);
  447.   InitHints;
  448.   ActiveChanged;
  449. end;
  450.  
  451. Procedure tIsamNavigator.SetBrowser(Value: TIsamBrowser);
  452. begin
  453.   FBrowser:= Value;
  454. end;
  455.  
  456. {tIsamNavButton}
  457.  
  458. destructor tIsamNavButton.Destroy;
  459. begin
  460.   if FRepeatTimer <> nil then
  461.     FRepeatTimer.Free;
  462.   inherited Destroy;
  463. end;
  464.  
  465. procedure tIsamNavButton.MouseDown(Button: TMouseButton; Shift: TShiftState;
  466.   X, Y: Integer);
  467. begin
  468.   inherited MouseDown (Button, Shift, X, Y);
  469.   if nsAllowTimer in FNavStyle then
  470.   begin
  471.     if FRepeatTimer = nil then
  472.       FRepeatTimer := TTimer.Create(Self);
  473.  
  474.     FRepeatTimer.OnTimer := TimerExpired;
  475.     FRepeatTimer.Interval := InitRepeatPause;
  476.     FRepeatTimer.Enabled  := True;
  477.   end;
  478. end;
  479.  
  480. procedure tIsamNavButton.MouseUp(Button: TMouseButton; Shift: TShiftState;
  481.                                   X, Y: Integer);
  482. begin
  483.   inherited MouseUp (Button, Shift, X, Y);
  484.   if FRepeatTimer <> nil then
  485.     FRepeatTimer.Enabled  := False;
  486. end;
  487.  
  488. procedure tIsamNavButton.TimerExpired(Sender: TObject);
  489. begin
  490.   FRepeatTimer.Interval := RepeatPause;
  491.   if (FState = bsDown) and MouseCapture then
  492.   begin
  493.     try
  494.       Click;
  495.     except
  496.       FRepeatTimer.Enabled := False;
  497.       raise;
  498.     end;
  499.   end;
  500. end;
  501.  
  502. procedure tIsamNavButton.Paint;
  503. var
  504.   R: TRect;
  505. begin
  506.   inherited Paint;
  507.   if (GetFocus = Parent.Handle) and
  508.      (FIndex = TIsamNavigator (Parent).FocusedButton) then
  509.   begin
  510.     R := Bounds(0, 0, Width, Height);
  511.     InflateRect(R, -3, -3);
  512.     if FState = bsDown then
  513.       OffsetRect(R, 1, 1);
  514.     DrawFocusRect(Canvas.Handle, R);
  515.   end;
  516. end;
  517.                 
  518. end.
  519.